<script lang="ts" setup>
import type { BpmProcessInstanceApi } from '#/api/bpm/processInstance';
import type { SystemUserApi } from '#/api/system/user';

import { nextTick, onMounted, ref, shallowRef, watch } from 'vue';
/**
 * 返回列表页
 */
import { useRouter } from 'vue-router';

import { Page } from '@vben/common-ui';
import {
  BpmModelFormType,
  BpmModelType,
  BpmTaskStatusEnum,
  DICT_TYPE,
} from '@vben/constants';
import { formatDateTime } from '@vben/utils';

// Element Plus 组件导入
import {
  ElAvatar,
  ElCard,
  ElCol,
  ElMessage,
  ElRow,
  ElTabPane,
  ElTabs,
} from 'element-plus';

import {
  getApprovalDetail as getApprovalDetailApi,
  getProcessInstanceBpmnModelView,
} from '#/api/bpm/processInstance';
import { getSimpleUserList } from '#/api/system/user';
import DictTag from '#/components/dict-tag/dict-tag.vue';
import { setConfAndFields2 } from '#/components/form-create';
import { registerComponent } from '#/utils/index';
import {
  SvgBpmApproveIcon,
  SvgBpmCancelIcon,
  SvgBpmRejectIcon,
  SvgBpmRunningIcon,
} from '#/views/bpm/processInstance/detail/modules/icons';

import ProcessInstanceBpmnViewer from './modules/bpm-viewer.vue';
import ProcessInstanceOperationButton from './modules/operation-button.vue';
import ProcessInstanceSimpleViewer from './modules/simple-bpm-viewer.vue';
import BpmProcessInstanceTaskList from './modules/task-list.vue';
import ProcessInstanceTimeline from './modules/time-line.vue';

defineOptions({ name: 'BpmProcessInstanceDetail' });

const props = defineProps<{
  activityId?: string; // 流程活动编号，用于抄送查看
  id: string; // 流程实例的编号
  taskId?: string; // 任务编号
}>();

enum FieldPermissionType {
  /**
   * 隐藏
   */
  NONE = '3',
  /**
   * 只读
   */
  READ = '1',
  /**
   * 编辑
   */
  WRITE = '2',
}

// 响应式数据
const processInstanceLoading = ref(false);
const processInstance = ref<BpmProcessInstanceApi.ProcessInstance>();
const processDefinition = ref<any>({});
const processModelView = ref<any>({});
const operationButtonRef = ref();
const activeTab = ref('form');
const taskListRef = ref();
const userOptions = ref<SystemUserApi.User[]>([]);
const activityNodes = ref<BpmProcessInstanceApi.ApprovalNodeInfo[]>([]);

// 表单相关
const fApi = ref<any>();
const detailForm = ref({
  rule: [],
  option: {},
  value: {},
});
const writableFields: Array<string> = [];
const BusinessFormComponent = shallowRef<any>(null);

// 图标映射
const auditIconsMap: Record<string, any> = {
  [BpmTaskStatusEnum.RUNNING]: SvgBpmRunningIcon,
  [BpmTaskStatusEnum.APPROVE]: SvgBpmApproveIcon,
  [BpmTaskStatusEnum.REJECT]: SvgBpmRejectIcon,
  [BpmTaskStatusEnum.CANCEL]: SvgBpmCancelIcon,
  [BpmTaskStatusEnum.APPROVING]: SvgBpmApproveIcon,
  [BpmTaskStatusEnum.RETURN]: SvgBpmRejectIcon,
  [BpmTaskStatusEnum.WAIT]: SvgBpmRunningIcon,
};

// 方法定义
/**
 * 加载流程详情
 */
const loadProcessDetail = async () => {
  await Promise.all([getApprovalDetail(), getProcessModelView()]);
};

/**
 * 获取审批详情
 */
const getApprovalDetail = async () => {
  processInstanceLoading.value = true;
  try {
    const param = {
      processInstanceId: props.id,
      activityId: props.activityId,
      taskId: props.taskId,
    };
    const data = await getApprovalDetailApi(param);

    if (!data) {
      ElMessage.error('查询不到审批详情信息！');
      return;
    }

    if (!data.processDefinition || !data.processInstance) {
      ElMessage.error('查询不到流程信息！');
      return;
    }

    processInstance.value = data.processInstance;
    processDefinition.value = data.processDefinition;
    // 处理表单显示
    await handleFormDisplay(data);

    // 设置审批节点信息
    activityNodes.value = data.activityNodes || [];

    // 加载待办任务
    operationButtonRef.value?.loadTodoTask(data.todoTask);
  } catch (error) {
    console.error('获取审批详情失败:', error);
    ElMessage.error('获取审批详情失败！');
  } finally {
    processInstanceLoading.value = false;
  }
};

/**
 * 处理表单显示
 */
const handleFormDisplay = async (data: any) => {
  if (processDefinition.value.formType === BpmModelFormType.NORMAL) {
    await handleNormalForm(data);
  } else if (processDefinition.value.formType === BpmModelFormType.CUSTOM) {
    await handleCustomForm();
  }
};

/**
 * 处理普通表单
 */
const handleNormalForm = async (data: any) => {
  const formFieldsPermission = data.formFieldsPermission;

  // 设置表单配置和字段
  if (detailForm.value.rule?.length > 0) {
    detailForm.value.value = processInstance.value?.formVariables || {};
  } else {
    setConfAndFields2(
      detailForm,
      processDefinition.value.formConf,
      processDefinition.value.formFields,
      processInstance.value?.formVariables || {},
    );
  }

  await nextTick();

  // 设置表单权限
  fApi.value?.btn.show(false);
  fApi.value?.resetBtn.show(false);
  fApi.value?.disabled(true);

  if (formFieldsPermission) {
    Object.keys(formFieldsPermission).forEach((field) => {
      setFieldPermission(field, formFieldsPermission[field]);
    });
  }
};

/**
 * 处理自定义表单
 */
const handleCustomForm = async () => {
  const formCustomViewPath = processDefinition.value?.formCustomViewPath;
  if (formCustomViewPath) {
    BusinessFormComponent.value = registerComponent(formCustomViewPath);
  } else {
    console.warn('自定义表单路径未配置');
  }
};

/**
 * 获取流程模型视图
 */
const getProcessModelView = async () => {
  try {
    if (BpmModelType.BPMN === processDefinition.value?.modelType) {
      processModelView.value = { bpmnXml: '' };
    }
    const data = await getProcessInstanceBpmnModelView(props.id);
    if (data) {
      processModelView.value = data;
    }
  } catch (error) {
    console.error('获取流程模型视图失败:', error);
    ElMessage.error('获取流程图失败！');
  }
};

/**
 * 设置字段权限
 */
const setFieldPermission = (field: string, permission: string) => {
  if (!fApi.value) return;

  switch (permission) {
    case FieldPermissionType.NONE: {
      fApi.value.hidden(true, field);
      break;
    }
    case FieldPermissionType.READ: {
      fApi.value.disabled(true, field);
      break;
    }
    case FieldPermissionType.WRITE: {
      fApi.value.disabled(false, field);
      writableFields.push(field);
      break;
    }
  }
};

/**
 * 刷新任务列表
 */
const refreshTaskList = () => {
  if (activeTab.value === 'record') {
    nextTick(() => {
      taskListRef.value?.refresh();
    });
  }
};

/**
 * 处理操作成功
 */
const handleOperationSuccess = () => {
  loadProcessDetail();
  refreshTaskList();
};

// 监听器
watch(
  () => activeTab.value,
  (newVal) => {
    if (newVal === 'record') {
      refreshTaskList();
    }
  },
);

// 生命周期
onMounted(async () => {
  await loadProcessDetail();

  // 加载用户列表
  try {
    userOptions.value = await getSimpleUserList();
  } catch (error) {
    console.error('获取用户列表失败:', error);
  }
});

const router = useRouter();
const handleBack = () => {
  // 返回到流程实例列表页
  router.push({
    path: '/bpm/instance',
  });

  // 或者返回上一页
  // router.go(-1)

  // 或者根据历史记录判断
  // if (window.history.state.back) {
  //   router.go(-1)
  // } else {
  //   router.push('/bpm/process-instance')
  // }
};
</script>

<template>
  <Page auto-content-height>
    <ElCard class="process-detail-card">
      <template #header>
        <div class="card-header">
          <div class="header-left">
            <ElButton text @click="handleBack" class="back-button">
              返回
            </ElButton>
            <span class="instance-id">编号：{{ id || '-' }}</span>
          </div>
        </div>
      </template>

      <div class="process-detail-content">
        <!-- 流程基本信息 - 移除底部边框 -->
        <div class="process-header">
          <div class="process-title-section">
            <div class="process-title">
              {{ processInstance?.name || '-' }}
            </div>
            <DictTag
              v-if="processInstance?.status"
              :type="DICT_TYPE.BPM_PROCESS_INSTANCE_STATUS"
              :value="processInstance.status"
              class="status-tag"
            />
          </div>

          <div class="process-meta-info">
            <div class="user-info">
              <ElAvatar
                :size="28"
                :src="processInstance?.startUser?.avatar"
                class="user-avatar"
              >
                <span
                  v-if="
                    !processInstance?.startUser?.avatar &&
                    processInstance?.startUser?.nickname
                  "
                >
                  {{ processInstance.startUser.nickname.substring(0, 1) }}
                </span>
              </ElAvatar>
              <span class="user-name">
                {{ processInstance?.startUser?.nickname || '-' }}
              </span>
            </div>
            <div class="submit-time">
              {{ formatDateTime(processInstance?.startTime) }} 提交
            </div>
          </div>

          <component
            v-if="
              processInstance?.status && auditIconsMap[processInstance.status]
            "
            :is="auditIconsMap[processInstance.status]"
            class="process-status-icon"
          />
        </div>

        <!-- 流程操作区域 -->
        <div class="process-tabs-wrapper">
          <ElTabs v-model="activeTab" class="process-detail-tabs">
            <!-- 审批详情标签 -->
            <ElTabPane label="审批详情" name="form">
              <ElRow :gutter="48" class="form-tab-content">
                <ElCol :xs="24" :sm="24" :md="18" :lg="18" :xl="16">
                  <!-- 普通表单 -->
                  <div
                    v-if="
                      processDefinition?.formType === BpmModelFormType.NORMAL
                    "
                    class="form-container"
                  >
                    <form-create
                      v-model="detailForm.value"
                      v-model:api="fApi"
                      :option="detailForm.option"
                      :rule="detailForm.rule"
                      class="dynamic-form"
                    />
                  </div>

                  <!-- 自定义表单 -->
                  <div
                    v-if="
                      processDefinition?.formType === BpmModelFormType.CUSTOM
                    "
                    class="custom-form-container"
                  >
                    <component
                      :is="BusinessFormComponent"
                      :id="processInstance?.businessKey"
                      v-if="BusinessFormComponent"
                    />
                    <div v-else class="form-placeholder">
                      自定义表单加载中...
                    </div>
                  </div>
                </ElCol>

                <ElCol :xs="24" :sm="24" :md="6" :lg="6" :xl="8">
                  <div class="timeline-section">
                    <ProcessInstanceTimeline :activity-nodes="activityNodes" />
                  </div>
                </ElCol>
              </ElRow>
            </ElTabPane>

            <!-- 流程图标签 -->
            <ElTabPane label="流程图" name="diagram">
              <div class="diagram-container">
                <!-- 简单流程图 -->
                <ProcessInstanceSimpleViewer
                  v-if="processDefinition.modelType === BpmModelType.SIMPLE"
                  :loading="processInstanceLoading"
                  :model-view="processModelView"
                  class="process-viewer"
                />

                <!-- BPMN流程图 -->
                <ProcessInstanceBpmnViewer
                  v-if="processDefinition.modelType === BpmModelType.BPMN"
                  :loading="processInstanceLoading"
                  :model-view="processModelView"
                  class="process-viewer"
                />

                <!-- 无流程图提示 -->
                <div
                  v-if="
                    !processDefinition.modelType ||
                    (processDefinition.modelType !== BpmModelType.SIMPLE &&
                      processDefinition.modelType !== BpmModelType.BPMN)
                  "
                  class="no-diagram"
                >
                  暂无流程图信息
                </div>
              </div>
            </ElTabPane>

            <!-- 流转记录标签 -->
            <ElTabPane label="流转记录" name="record">
              <div class="task-list-container">
                <BpmProcessInstanceTaskList
                  ref="taskListRef"
                  :loading="processInstanceLoading"
                  :id="id"
                />
              </div>
            </ElTabPane>

            <!-- 流转评论标签（待开发） -->
            <ElTabPane v-if="false" label="流转评论" name="comment">
              <div class="comment-placeholder">评论功能待开发</div>
            </ElTabPane>
          </ElTabs>
        </div>
      </div>

      <template #footer>
        <div class="operation-footer">
          <ProcessInstanceOperationButton
            ref="operationButtonRef"
            :process-instance="processInstance"
            :process-definition="processDefinition"
            :user-options="userOptions"
            :normal-form="detailForm"
            :normal-form-api="fApi"
            :writable-fields="writableFields"
            @success="handleOperationSuccess"
          />
        </div>
      </template>
    </ElCard>
  </Page>
</template>

<style lang="scss" scoped>
// 响应式设计
@media (max-width: 768px) {
  .process-detail-content {
    padding: 0 8px;
  }

  .process-title-section {
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
  }

  .process-meta-info {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
  }

  .process-status-icon {
    position: relative;
    width: 100px;
    height: 100px;
    margin-top: 0;
  }

  .form-tab-content {
    :deep(.el-col) {
      margin-bottom: 16px;
    }
  }
}

@media (max-width: 1200px) {
  .form-tab-content {
    :deep(.el-col) {
      width: 100%;
    }
  }
}

.process-detail-card {
  height: 100%;

  :deep(.el-card__body) {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 20px;
  }
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 700; /* 字体加粗 */
  .instance-id {
    font-size: 16px;
    font-weight: inherit; /* 继承父元素的字重 */
    color: var(--el-text-color-secondary);
  }

  .header-left {
    display: flex;
    gap: 16px;
    align-items: center;

    .back-button {
      display: flex;
      gap: 4px;
      align-items: center;
      padding: 4px 8px;
      color: var(--el-color-primary);
      cursor: pointer;
      background: transparent;
      border: none;
      transition: all 0.3s ease;

      &:hover {
        background: var(--el-fill-color-light);
        border-radius: 4px;
      }
    }

    .instance-id {
      font-size: 16px;
      font-weight: 700;
      color: var(--el-text-color-secondary);
    }
  }
}

.process-detail-content {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 20px;
  height: 100%;
}

.process-header {
  position: relative;
  // padding-bottom: 16px;

  /* 移除这行来去掉分割线 */

  /* border-bottom: 1px solid var(--el-border-color-light); */
}

.process-title-section {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-bottom: 20px;

  .process-title {
    font-size: 24px;
    font-weight: 600;
    line-height: 1.2;
    color: var(--el-text-color-primary);
  }

  .status-tag {
    flex-shrink: 0;
  }
}

.process-meta-info {
  display: flex;
  gap: 20px;
  align-items: center;

  .user-info {
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 4px 12px;
    background: var(--el-fill-color-light);
    border-radius: 16px;

    .user-avatar {
      flex-shrink: 0;
    }

    .user-name {
      font-size: 14px;
      color: var(--el-text-color-primary);
    }
  }

  .submit-time {
    font-size: 14px;
    color: var(--el-text-color-secondary);
  }
}

.process-status-icon {
  position: absolute;
  top: 0;
  right: 0;
  width: 144px;
  height: 144px;
  opacity: 0.9;
}

.process-tabs-wrapper {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 400px;
}

.form-tab-content {
  height: 100%;
  margin: 0 !important;

  :deep(.el-col) {
    display: flex;
    flex-direction: column;
  }
}

.form-container,
.custom-form-container {
  flex: 1;
  height: 100%;

  :deep(.dynamic-form) {
    height: 100%;

    .form-create {
      height: 100%;
    }
  }
}

.custom-form-container {
  .form-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 200px;
    font-size: 16px;
    color: var(--el-text-color-secondary);
  }
}

.timeline-section {
  height: 100%;
  margin-top: 0;
}

.diagram-container {
  position: relative;
  height: 100%;

  .process-viewer {
    height: 100%;
    min-height: 500px;
  }

  .no-diagram {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 300px;
    font-size: 16px;
    color: var(--el-text-color-secondary);
  }
}

.task-list-container {
  height: 100%;
  min-height: 400px;
}

.comment-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
  font-size: 16px;
  color: var(--el-text-color-secondary);
}

.operation-footer {
  padding: 0 16px;
}
</style>
